package com.dawn.module.hospital.service;

import cn.hutool.core.util.RandomUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.dawn.framework.common.exception.ServerException;
import com.dawn.framework.common.pojo.CommonResult;
import com.dawn.framework.common.util.http.HttpUtils;
import com.dawn.framework.common.util.json.JsonUtils;
import com.dawn.framework.web.core.util.WebFrameworkUtils;
import com.dawn.module.hospital.controller.app.inhospital.vo.InHospitalPreCreateReqVO;
import com.dawn.module.hospital.controller.app.inhospital.vo.InHospitalQueryReqVO;
import com.dawn.module.hospital.enums.BHConstants;
import com.dawn.module.hospital.enums.ErrorCodeConstants;
import com.dawn.module.hospital.util.RandomUtils;
import com.dawn.module.hospital.util.SecEncryptUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @description:
 * @author: cnsu-cmh
 * @time: 2024/10/17 15:32
 */
@Slf4j
@Service
public class InHospitalService extends BHService {

    @Autowired
    private PatientService patientService;

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private TemplateMsgService templateMsgService;

    @Autowired
    private EhealthService ehealthService;

    @Autowired
    private EInvoiceService eInvoiceService;

    @Autowired
    private RefundService refundService;

    public CommonResult record(InHospitalQueryReqVO reqVO) {
        Map params = new HashMap();
        String traceId = WebFrameworkUtils.getTraceId();
        params.put("traceId",traceId);
        params.put("hisProvider", BHConstants.HIS_PROVIDER);
        params.put("tradeSerialNumber", RandomUtil.randomNumbers(9));
        params.put("patientId",reqVO.getPatientId());
        params.put("pageNow","1");
        params.put("pageSize","1");
        params.put("inPatientId",reqVO.getInPatientId());

        return HttpUtils.getHttp(getHisServerUri() + BHConstants.HIS_GET_INHOSPITAL_RECORD.getValue(), params);
    }

    public CommonResult info(InHospitalQueryReqVO reqVO) {
        Map params = new HashMap();
        String traceId = WebFrameworkUtils.getTraceId();
        params.put("traceId",traceId);
        params.put("hisProvider", BHConstants.HIS_PROVIDER);
        params.put("tradeSerialNumber", RandomUtil.randomNumbers(9));
        params.put("patientId",reqVO.getPatientId());

        params.put("pageNow","1");
        params.put("pageSize","1");
        if(StringUtils.isEmpty(reqVO.getPatientId())){
            params.put("inPatientId","1");
        }else {
            params.put("inPatientId",reqVO.getInPatientId());
        }

        CommonResult hisResult =  HttpUtils.getHttp(getHisServerUri() + BHConstants.HIS_GET_INHOSPITAL_INFO.getValue(), params);
        Map map = new HashMap<>();
        if(hisResult.isSuccess()){
            Map dataMap = (Map) hisResult.getData();
            List<Map> inHospitalList = (List<Map>) dataMap.get("JBXX");
            List<Map> feeList = (List<Map>) dataMap.get("FYXX");
            List<Map> zdList = (List<Map>) dataMap.get("ZDXX");
            List<Map> ssList = (List<Map>) dataMap.get("SSXX");
            if(inHospitalList!=null && inHospitalList.size()>0){
                map.put("inHospital", inHospitalList.get(0));
            }
            map.put("feeList", feeList);
            map.put("zdList", zdList);
            map.put("ssList", ssList);
            map.put("dataMap", dataMap);
            return CommonResult.success(map);
        }
        return hisResult;
    }


    public CommonResult createOrder(InHospitalPreCreateReqVO reqVO) {
        //保存挂号信息
        Map params = new HashMap();
        params.put("userId",reqVO.getUserId());
        params.put("openid", reqVO.getOpenid());
        params.put("patientId", reqVO.getPatientId());
        params.put("name", reqVO.getPatientName());
        params.put("cardNo", reqVO.getCardNo());
        params.put("sex", reqVO.getSex());
        params.put("inDate", reqVO.getInDate());
        params.put("bedNo", reqVO.getBedNo());
        params.put("doctorName", reqVO.getDoctorName());
        params.put("departmentName",reqVO.getDepartmentName());
        params.put("amount",reqVO.getAmount());
        params.put("totalCost",reqVO.getTotalCost());
        params.put("inBalance",reqVO.getInBalance());
        params.put("prePayBalance",reqVO.getPrePayBalance());
        params.put("paycost","0");
        params.put("inPatientNo",reqVO.getInPatientNo());
        params.put("inPatientId",reqVO.getInPatientId());

        String orderNumber = "ZYYJ" + RandomUtils.buildRandomStr(4);
        params.put("orderNumber",orderNumber);
        params.put("tradeSerialNumber",orderNumber);

        if (BHConstants.ALIPAY_MINI_APPLET.getCode().equals(reqVO.getAppType())) {
            // 支付宝小程序
            if("chs".equals(reqVO.getPayType())) {
                params.put("payTypeID", BHConstants.PAY_CARD_ALI_CHS_CODE);
                params.put("payModeName", BHConstants.PAY_CARD_ALI_CHS_HIS);
            } else {
                params.put("payTypeID", BHConstants.PAY_CARD_ALI_CODE);
                params.put("payModeName", BHConstants.PAY_CARD_ALI_HIS);
            }
            params.put("payPlatform", BHConstants.PAY_PLATFORM_TYPE_ALI);
            params.put("payScene", BHConstants.ALIPAY_MINI_APPLET.getMsg());
        } else if(BHConstants.WEIXIN_SERVICE_ACCOUNTS.getCode().equals(reqVO.getAppType())){
            // 微信公众号
            if("chs".equals(reqVO.getPayType())) {
                // TODO 待HIS给出数据后修改
                params.put("payTypeID", BHConstants.PAY_CARD_WX_CHS_CODE);
                params.put("payModeName", BHConstants.PAY_CARD_WX_CHS_HIS);
            } else {
                params.put("payTypeID", BHConstants.PAY_CARD_WX_CODE);
                params.put("payModeName", BHConstants.PAY_CARD_WX_HIS);
            }

            params.put("payPlatform", BHConstants.PAY_PLATFORM_TYPE_WX_NAME);
            params.put("payScene", BHConstants.WEIXIN_SERVICE_ACCOUNTS.getMsg());
        }

        CommonResult result = HttpUtils.postForm(getHisServerUri() + BHConstants.HIS_ADD_INHOSPITAL_PRE.getValue(), params);
        if(result.isError()) {
            return result;
        }
        JSONObject orderDetails = new JSONObject();
        orderDetails.put("patientName", reqVO.getPatientName());
        orderDetails.put("patientId", reqVO.getPatientId());
        orderDetails.put("cardNo", reqVO.getCardNo());
        orderDetails.put("clinicNo", reqVO.getClinicNo());
        orderDetails.put("userId", reqVO.getUserId());
        orderDetails.put("openid", reqVO.getOpenid());
        orderDetails.put("pid", reqVO.getPId());

        orderDetails.put("billMap",reqVO);
        orderDetails.put("orderNumber",orderNumber);
        orderDetails.put("orderName",reqVO.getOrderName());
        orderDetails.put("totalCost",reqVO.getAmount());

        orderDetails.put("inPatientNo",reqVO.getInPatientNo());
        orderDetails.put("inPatientId",reqVO.getInPatientId());

        stringRedisTemplate.opsForValue().set("OrderDetails_"+orderNumber,orderDetails.toJSONString(),30L, TimeUnit.MINUTES);

        JSONObject orderData = new JSONObject();
        orderData.put("orderNumber", orderNumber);
        return CommonResult.success(orderData);
    }

    public CommonResult queryByOrderNumber(String orderNumber) {
        Map params = new HashMap();
        params.put("orderNumber",orderNumber);
        CommonResult result = HttpUtils.getHttp(getHisServerUri() + BHConstants.HIS_GET_INHOSPITAL_ORDER.getValue(), params);
        return result;
    }


    public CommonResult buildPaySignData(String orderNumber) {
        Object orderObj = stringRedisTemplate.opsForValue().get("OrderDetails_" + orderNumber);
        if(orderObj == null) {
            return CommonResult.error(ErrorCodeConstants.BH_ERROR.getCode(), "订单数据不存在或已失效");
        }
        String cacheOrderData = orderObj.toString();
        JSONObject prePayInfo = JSON.parseObject(cacheOrderData);

        Map<String,Object> map = new HashMap<>();
        map.putAll(prePayInfo);
        JSONObject signDataJson = new JSONObject();
        signDataJson.put("patientId",prePayInfo.getString("patientId"));
        signDataJson.put("patientName",prePayInfo.getString("patientName"));
        signDataJson.put("clinicNo",prePayInfo.getString("inPatientId"));
        signDataJson.put("cardNo",prePayInfo.getString("cardNo"));
        signDataJson.put("pid",prePayInfo.getString("pid"));
        signDataJson.put("userId",prePayInfo.getString("userId"));
        signDataJson.put("openid",prePayInfo.getString("openid"));
        signDataJson.put("inPatientNo",prePayInfo.getString("inPatientNo"));
        signDataJson.put("inPatientId",prePayInfo.getString("inPatientId"));
        signDataJson.put("registerNo",prePayInfo.getString("inPatientNo"));
        signDataJson.put("orderName",prePayInfo.getString("orderName"));
        signDataJson.put("totalCost",prePayInfo.getString("totalCost"));
        signDataJson.put("orderNumber",orderNumber);

        String signData = null;
        try {
            signData = SecEncryptUtil.encryption(signDataJson.toJSONString());
        } catch (Exception e) {
            throw new ServerException(ERROR_CODE,e.getMessage());
        }
        map.put("signDataStr", signData);
        return CommonResult.success(map);
    }


    public CommonResult payNotify(Map params) {
        log.info("---------住院预交缴费成功通知-------params:"+ JSONUtil.toJsonStr(params));

//        Long pId = Long.valueOf(params.get("patientId").toString());
        String orderNumber = String.valueOf(params.get("orderNumber")) ;
        String thirdOrderNo = String.valueOf(params.get("thirdOrderNo")) ;
        String openid = String.valueOf(params.get("openid")) ;
        String totalCost = String.valueOf(params.get("totalCost")) ;
        String payInfo = String.valueOf(params.get("payInfo")) ;

//        CommonResult patientResult = patientService.findPatientById(pId);
//        JSONObject patient = (JSONObject)patientResult.getData();

        CommonResult findResult = queryByOrderNumber(orderNumber);
        if(!findResult.isSuccess()) {
            return findResult;
        }
        JSONObject orderObj = (JSONObject)findResult.getData();
        if(StringUtils.hasLength(orderObj.getString("procedureStatus"))) {
            String procedureStatus = orderObj.getString("procedureStatus");
            if("success".equals(procedureStatus)) {
                return CommonResult.success("操作成功");
            }
            if("fails".equals(procedureStatus)) {
                return CommonResult.success("操作成功");
            }
        }
        String payScene = orderObj.getString("payScene");

        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("hisProvider", BHConstants.HIS_PROVIDER);
        paramMap.put("partnerCompany",BHConstants.COMPANY_NAME);
        paramMap.put("tradeSerialNumber", RandomUtil.randomNumbers(9));
        paramMap.put("orderNumber",orderNumber);
        paramMap.put("thirdOrderNo",thirdOrderNo);
        paramMap.put("payInfo", JsonUtils.toJsonString(payInfo));

        if(BHConstants.ALIPAY_MINI_APPLET.getMsg().equals(payScene)) {
            paramMap.put("payWay", BHConstants.PAY_CARD_ALI_CODE);
        } else {
            paramMap.put("payWay", BHConstants.PAY_CARD_WX_CODE);
        }

        CommonResult payResult = HttpUtils.postForm(getHisServerUri() + BHConstants.HIS_PAY_INHOSPITAL.getValue(), paramMap);
        if (payResult.isSuccess()) {

            JSONObject resultData = (JSONObject)payResult.getData();

            // 微信公众号
            if(BHConstants.WEIXIN_SERVICE_ACCOUNTS.getMsg().equals(payScene)) {
                // TODO 推送微信模板信息
                templateMsgService.sendMsgInHospitalPre(orderObj);
                // TODO 上传数据到电子健康卡
                // 上传数据到电子健康卡
                if(StringUtils.hasLength(getEhealthCfg().getHospitalId())) {
                    try{
//                        String ehealthCardId = patient.getString("ehealthCardId");
//                        if(StringUtils.hasLength(ehealthCardId)) {
//
//                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }

                // 开据电子票据
                try{
                    CommonResult eReceiptResult = eInvoiceService.open(BHConstants.ORDER_TYPE_PRE_PAYMENT,resultData);
                    log.warn(orderNumber + "开据电子票据" + orderNumber + JsonUtils.toJsonString(eReceiptResult));
                } catch (Exception e) {
                    e.printStackTrace();
                    log.warn("电子票据开据失败 " + orderNumber);
                }
            }
            // 支付宝小程序
            if(BHConstants.ALIPAY_MINI_APPLET.equals(payScene)) {

            }
        } else {
            // 支付数据回写HIS失败
            // 推送退费审核模板消息
            refundService.saveRefundExamine(BHConstants.ORDER_TYPE_PRE_PAYMENT,orderObj,payResult.getMsg());

            return CommonResult.success(payResult.getMsg());
        }
        return CommonResult.success("");
    }

    public CommonResult preRecord(InHospitalQueryReqVO reqVO) {
        Map params = new HashMap();
        String traceId = WebFrameworkUtils.getTraceId();
        params.put("traceId",traceId);
        params.put("hisProvider", BHConstants.HIS_PROVIDER);
        params.put("tradeSerialNumber", RandomUtil.randomNumbers(9));
        params.put("patientId",reqVO.getPatientId());
        return HttpUtils.getHttp(getHisServerUri() + BHConstants.HIS_HIS_INHOSPITAL_PRE_RECORD.getValue(), params);
    }

    public CommonResult payRecord(InHospitalQueryReqVO reqVO) {
        Map params = new HashMap();
        String traceId = WebFrameworkUtils.getTraceId();
        params.put("traceId",traceId);
        params.put("hisProvider", BHConstants.HIS_PROVIDER);
        params.put("tradeSerialNumber", RandomUtil.randomNumbers(9));
        params.put("inPatientNo",reqVO.getInPatientNo());

        return HttpUtils.getHttp(getHisServerUri() + BHConstants.HIS_HIS_INHOSPITAL_PAY_RECORD.getValue(), params);
    }

    public CommonResult dailyRecord(InHospitalQueryReqVO reqVO) {
        Map params = new HashMap();
        String traceId = WebFrameworkUtils.getTraceId();
        params.put("traceId",traceId);
        params.put("hisProvider", BHConstants.HIS_PROVIDER);
        params.put("tradeSerialNumber", RandomUtil.randomNumbers(9));
        params.put("patientId",reqVO.getPatientId());
        params.put("inPatientNo",reqVO.getInPatientNo());
        params.put("searchDate", reqVO.getSearchDate());
        if(!StringUtils.isEmpty(reqVO.getInPatientId())){
            params.put("inPatientId",reqVO.getInPatientId());//<RID>1</RID>
        }else {
            params.put("inPatientId",1);//<RID>1</RID>
        }
        return HttpUtils.getHttp(getHisServerUri() + BHConstants.HIS_HIS_INHOSPITAL_DAILY_RECORD.getValue(), params);
    }

    public CommonResult totalCost(InHospitalQueryReqVO reqVO) {
        Map params = new HashMap();
        String traceId = WebFrameworkUtils.getTraceId();
        params.put("traceId",traceId);
        params.put("hisProvider", BHConstants.HIS_PROVIDER);
        params.put("patientId",reqVO.getPatientId());
        params.put("inPatientNo",reqVO.getInPatientNo());
        params.put("fllx",reqVO.getCostType());
        if(!StringUtils.isEmpty(reqVO.getInPatientId())){
            params.put("inPatientId",reqVO.getInPatientId());//<RID>1</RID>
        }else {
            params.put("inPatientId",1);//<RID>1</RID>
        }
        return HttpUtils.getHttp(getHisServerUri() + BHConstants.HIS_HIS_INHOSPITAL_TOTAL_COST.getValue(), params);
    }


}
